/*
 * image.h
 *
 *  Created on: 2024年2月28日
 *      Author: 陈朝
 */
#ifndef IMAGE_H
#define IMAGE_H

#include "zf_common_headfile.h"
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

// 数据类型定义
typedef signed char int8;
typedef signed short int int16;
typedef signed int int32;
typedef unsigned char uint8;
typedef unsigned short int uint16;
typedef unsigned int uint32;

// 颜色定义
#define USER_RED     0xF800    //红色
#define USER_GREEN   0x07E0    //绿色
#define USER_BLUE    0x001F    //蓝色

// 图像处理参数
#define WHITE_PIXEL 255
#define BLACK_PIXEL 0
#define BORDER_MAX  UVC_WIDTH-2 
#define BORDER_MIN  1 
#define USE_NUM     UVC_HEIGHT*3 

// 赛道元素类型
typedef enum {
    NORMAL_TRACK = 0,   // 普通赛道
    CROSS_TRACK,        // 十字路口
    ZEBRA_TRACK,        // 斑马线
    CIRCLE_TRACK        // 圆环
} TrackType;



// 状态机状态
typedef enum {
    SEARCH_MODE = 0,    // 搜索模式
    TRACKING_MODE,      // 跟踪模式
    SPECIAL_MODE        // 特殊元素处理模式
} StateType;

// 全局变量声明
extern int midline[UVC_HEIGHT];
extern int leftline[UVC_HEIGHT];
extern int rightline[UVC_HEIGHT];
extern uint8 binaryArray[UVC_HEIGHT][UVC_WIDTH];
extern uint8 original_image[UVC_HEIGHT][UVC_WIDTH];
extern uint8 bin_image[UVC_HEIGHT][UVC_WIDTH];
extern TrackType current_track_type;
extern StateType current_state;
extern uint8_t emergency_stop;  // 紧急停止标志



// 八邻域相关变量
extern uint16 points_l[USE_NUM][2]; // 左线点
extern uint16 points_r[USE_NUM][2]; // 右线点
extern uint16 dir_r[USE_NUM];       // 右边生长方向
extern uint16 dir_l[USE_NUM];       // 左边生长方向
// extern uint16 data_stastics_l;      // 左边找到点的个数
// extern uint16 data_stastics_r;      // 右边找到点的个数
extern uint16 l_border[UVC_HEIGHT]; // 左线数组
extern uint16 r_border[UVC_HEIGHT]; // 右线数组
extern uint8 center_line[UVC_HEIGHT]; // 中线数组



// 十字处理相关变量
extern uint8 flag_cross;         // 十字标志位
extern int cross_jud;            // 十字状态判断

//斑马线相关变量
extern uint8 zebra_detected;     // 斑马线检测标志
extern uint16 change_point;      // 变化点计数器
extern struct timeval last_zebra_time;
extern uint8 zebra_count;             // 斑马线检测计数
#define ZEBRA_MIN_INTERVAL 3000       // 两次斑马线检测的最小间隔时间(ms)

//圆环相关变量
extern uint8_t cir_stage;
extern uint8_t Cir_hengyi_Flag;
extern uint8 left_right_flag;
extern int16_t r_lose_num;
extern int16_t l_lose_num;
extern int16 length;
extern uint8_t l_dir_sum[9];
extern uint8_t r_dir_sum[9];

// 函数声明
short GetOSTU(uint8 tmImage[UVC_HEIGHT][UVC_WIDTH]);
void Bin_Image_Filter(uint8 Bin_Image[UVC_HEIGHT][UVC_WIDTH]);
// int my_abs(int value);
int16 limit_a_b(int16 x, int a, int b);
int16 limit1(int16 x, int16 y);
uint8 otsuThreshold(uint8 *image, uint16 col, uint16 row);
void turn_to_bin(void);
uint8 get_start_point(uint8 start_row);
void search_l_r(uint16 break_flag, uint8(*image)[UVC_WIDTH], uint16 *l_stastic, uint16 *r_stastic, uint8 l_start_x, uint8 l_start_y, uint8 r_start_x, uint8 r_start_y, uint8*hightest);
void get_left(uint16 total_L);
void get_right(uint16 total_R);
void image_filter(uint8(*bin_image)[UVC_WIDTH]);
void image_draw_rectan(uint8(*image)[UVC_WIDTH]);
void calculate_s_i(uint8 start, uint8 end, uint16 *border, float *slope_rate, float *intercept);
float Slope_Calculate(uint8 begin, uint8 end, uint16 *border);
void cross_fill(uint8(*image)[UVC_WIDTH], uint16 *l_border, uint16 *r_border, 
               uint16 total_num_l, uint16 total_num_r,
               uint16 *dir_l, uint16 *dir_r, 
               uint16(*points_l)[2], uint16(*points_r)[2]); 



//圆环相关变量
extern uint8_t cir_stage;
extern uint8_t Cir_hengyi_Flag;
extern uint8 left_right_flag;
extern int16_t r_lose_num;
extern int16_t l_lose_num;
extern int16 length;
extern uint8_t l_dir_sum[9];
extern uint8_t r_dir_sum[9];
extern uint16 l_index[UVC_HEIGHT];  // 左边界索引数组
extern uint16 r_index[UVC_HEIGHT];  // 右边界索引数组

//圆环判断函数
bool iscircle(unsigned char *l, unsigned char *r, unsigned char(*p)[UVC_WIDTH]);
bool liscircle2(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool lfixcircle2(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool liscircle3(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool lfixcircle3(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool liscircle4(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool lfixcircle4(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool liscircle5(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool liscircle6(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool lfixcircle6(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool liscircle7(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool lfixcircle7(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool liscircle8(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool liscircle9(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexl);
bool riscircle2(uint8 *l, uint8 *r, uint8(*p)[UVC_WIDTH], uint16 *indexr);  
void circletemp(unsigned char(*img)[UVC_WIDTH], unsigned char *l, unsigned char *r);     

// 状态机
void state_machine_init(void);
void detect_track_type(void);
void cross_track_process(void);
void normal_track_process(void);
void circle_track_process(void);
void image_process();

#endif // IMAGE_H